/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.srf;

import com.hp.hpl.jena.vocabulary.RDF;
import edu.yonsei.iwb.di.ESService;
import edu.yonsei.iwb.ts.TSSearch;
import edu.yonsei.iwb.ts.model.Triple;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;
import java.util.Vector;

/**
 *
 * @author dk
 */
public class TIPartitional {

    private Vector<String> trainingSet;
    private Vector<String> testSet;
    private Vector<String> valueList;
    
    private Hashtable<String, String> trct;
    private double rate;
    private String targetclass;
    private String targetProperty;
    private String runID;
    private ESService di;
    private TSSearch ts;

    @Deprecated
    public TIPartitional(String tc, String tp, double rate, String runid) {
        this.targetclass = tc;
        this.targetProperty = tp;
        this.trainingSet = new Vector();
        this.testSet = new Vector();
        this.valueList = new Vector();
        this.trct = new Hashtable();
        this.rate = rate;
        this.runID = runid;
    }

    public TIPartitional(String tc, String tp, String indexname, double rate, String runid) {
        this.di = new ESService();
        this.ts = new TSSearch(new String[]{indexname});
        this.targetclass = tc;
        this.targetProperty = tp;
        this.trainingSet = new Vector();
        this.testSet = new Vector();
        this.valueList = new Vector();
        this.trct = new Hashtable();
        this.rate = rate;
        this.runID = runid;
    }
    
    public TIPartitional(String tc, String tp, String[] indexname, double rate, String runid) {
        this.di = new ESService();
        this.ts = new TSSearch(indexname);
        this.targetclass = tc;
        this.targetProperty = tp;
        this.trainingSet = new Vector();
        this.testSet = new Vector();
        this.valueList = new Vector();
        this.trct = new Hashtable();
        this.rate = rate;
        this.runID = runid;
    }

    public Vector<String> getTrainingSet() {
        return this.trainingSet;
    }

    public Vector<String> getTestSet() {
        return this.testSet;
    }

    public void initialize() throws IOException {
        makeDataset();
//        writeFile();
    }
    
    public String getTrainingMsg(){
        StringBuilder pw1 = new StringBuilder();
        for (int i = 0; i < trainingSet.size(); i++) {
            String ins = trainingSet.get(i);
            pw1.append(ins).append("\t").append(this.trct.get(ins)).append("\n");
        }
        return pw1.toString();
    }
    
    public String getTestMsg(){
        StringBuilder pw1 = new StringBuilder();
        for (int i = 0; i < testSet.size(); i++) {
            String ins = testSet.get(i);
            pw1.append(ins).append("\t").append(this.trct.get(ins)).append("\n");
        }
        return pw1.toString();
    }
    
    public String getValueMsg(){
        StringBuilder pw1 = new StringBuilder();
        for (int i = 0; i < valueList.size(); i++) {
            String value = valueList.get(i);
            pw1.append(value).append("\t").append(i).append("\n");
        }
        return pw1.toString();
    }

    private void writeFile() throws UnsupportedEncodingException, FileNotFoundException {
        File dir = new File("./dataset/" + this.runID);
        dir.mkdirs();
        File trainf = new File("./dataset/" + this.runID + "/training.tsv");
        File testf = new File("./dataset/" + this.runID + "/test.tsv");
        File vlist = new File("./dataset/" + this.runID + "/vlist.tsv");
        PrintWriter pw1 = new PrintWriter(new OutputStreamWriter(new FileOutputStream(trainf), "euc-kr"));
        for (int i = 0; i < trainingSet.size(); i++) {
            String ins = trainingSet.get(i);
            pw1.write(ins + "\t" + this.trct.get(ins) + "\n");
        }
        pw1.flush();
        pw1.close();

        PrintWriter pw2 = new PrintWriter(new OutputStreamWriter(new FileOutputStream(testf), "euc-kr"));
        for (int i = 0; i < testSet.size(); i++) {
            String ins = testSet.get(i);
            pw2.write(ins + "\t" + this.trct.get(ins) + "\n");
        }
        pw2.flush();
        pw2.close();

        PrintWriter pw3 = new PrintWriter(new OutputStreamWriter(new FileOutputStream(vlist), "euc-kr"));
        for (int i = 0; i < valueList.size(); i++) {
            String value = valueList.get(i);
            pw3.write(value + "\t" + i + "\n");
        }
        pw3.flush();
        pw3.close();

    }

    private void makeDataset() throws IOException {
        ArrayList<String> tisetarray = TSSearch.listSubjectResource(RDF.type.getURI(), this.targetclass);

        ArrayList<String> tiList = new ArrayList();
//        ArrayList<String> valueList = new ArrayList();

        ArrayList<Triple> obset = TSSearch.listTriple(null, targetProperty, null);
        for (int i = 0; i < obset.size(); i++) {
            Triple triple = obset.get(i);
            String su = triple.getSubject();

            if (tisetarray.contains(su)) {
                if (!tiList.contains(su)) {
                    tiList.add(su);
                    this.trainingSet.add(su);

                    String value = triple.getObject().getValue();
                    if (!valueList.contains(value)) {
                        valueList.add(value);
                    }

                    trct.put(su, value);
                }
            }
        }

        int totalSize = tiList.size();
        double testSetSize = totalSize * this.rate;
        int s = (int) testSetSize;

        Random seedOfseed = new Random();
        int seed = seedOfseed.nextInt(1000);
        Random random = new Random(seed);
        int size = (s / valueList.size());
        int current = 0;

        Hashtable<String, ArrayList<String>> sltiset = new Hashtable();
        for (int j = 0; j < valueList.size(); j++) {
            String value = valueList.get(j);
            sltiset.put(value, new ArrayList<String>());
        }

        while (true) {
            int index = random.nextInt(totalSize);
            String vv = tiList.get(index);
            String value = trct.get(vv);
//            int valueid = valueList.indexOf(value);

            ArrayList<String> tis = sltiset.get(value);
            if (tis.size() < size + 1) {
                String subject = tiList.get(index);
                if (!tis.contains(subject)) {
                    tis.add(subject);
                    this.testSet.add(subject);
                    this.trainingSet.remove(subject);
                }
                current++;
            }

            if (testSetSize < current) {
                break;
            }
        }

    }

    public static void main(String[] args) throws IOException {
//        String tc = "http://localhost/foo#Person";        
//        String tp = "http://localhost/foo#isUncle";        
//        String indexName = "forte";
//        String runID = "forte1";

//        String tc = "http://www.co-ode.org/roberts/family-tree.owl#Person";
//        String tp = "http://www.co-ode.org/roberts/family-tree.owl#isUncle";
//        String indexName = "family2";
//        String runID = "family1";

        String tc = "http://www.co-ode.org/roberts/family-tree.owl#Person";
        String tp = "http://www.co-ode.org/roberts/family-tree.owl#isAunt";
        String indexName = "family2";
        String runID = "family_a1";

//        String tc = "http://iweb.yonsei.ac.kr/ontologies/smarttv/Media";        
//        String tp = "http://iweb.yonsei.ac.kr/ontologies/smarttv/targetproperty";        ;
//        String indexName = "smarttv";
//        String runID = "media1";

        double rate = 0.2;

        TIPartitional tip = new TIPartitional(tc, tp, indexName, rate, runID);
        tip.initialize();

    }
}
